<!-- src/components/attraction/CommentSection.vue -->
<template>
  <div class="comment-section">
    <h2>评论区</h2>

    <!-- 评论输入框 -->
    <div class="comment-input">
      <el-input
        v-model="newComment"
        type="textarea"
        :rows="3"
        placeholder="写下你的评论..."
      />
      <div class="comment-actions">
        <el-upload
          list-type="picture-card"
          ref="upload"
          :limit="3"
          v-model:file-list="uploadedImages"
          action="/Image/upload/file"
          :auto-upload="false"
          :on-preview="handlePictureCardPreview"
          :on-change="handleChange"
          :on-exceed="handleExceed"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>
        <!-- 预览-->
        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="" />
        </el-dialog>
        <el-button type="primary" @click="submitComment">发表评论</el-button>
      </div>
    </div>

    <!-- 评论列表 -->
    <div class="comment-list">
      <el-scrollbar>
        <div class="list-container" v-infinite-scroll="loadMore" :infinite-scroll-disabled="loading || !hasMore"
             infinite-scroll-distance="5">
      <el-card v-for="comment in comments" :key="comment.commentId" class="comment-item">
        <div class="comment-header">
          <div class="user-info">
            <el-avatar :src="comment.user.avatarUrl" />
            <span class="username">{{ comment.user.username }}</span>
          </div>
          <span class="comment-time">{{ formatDate(comment.createdAt) }}</span>
        </div>

        <div class="comment-content">
          <p>{{ comment.content }}</p>
          <div v-if="comment.imageUrls?.length" class="comment-images">
            <el-image
              v-for="(url, index) in comment.imageUrls"
              :key="index"
              :src="url"
              :preview-src-list="comment.imageUrls"
            />
          </div>
        </div>

        <div class="comment-footer">
          <el-button
            type="primary"
            @click="likeComment(comment)"
            link
          >
            <img
              v-if="!comment.isLikedByCurrentUser"
              :src="thumbIcon"
              alt="点赞"
              width="20"
              height="20"
            />
            <img
              v-if="comment.isLikedByCurrentUser"
              :src="thumbLikedIcon"
              alt="已点赞"
              width="20"
              height="20"
            />
            {{ comment.likeCount }}
          </el-button>
          <el-button
            v-if="comment.userId === currentUserId"
            type="danger"
            link
            @click="deleteComment(comment.commentId,comment.imageUrls)"
          >
            删除
          </el-button>
        </div>
      </el-card>
          <!-- 加载提示 -->
          <div v-if="loading" class="loading-tip">
            正在加载中...
          </div>

          <!-- 显示剩余评论数 -->
          <div v-if="!loading && hasMore" class="more-tip">
            还有 {{ totalComments - loadedComments }} 条评论，继续下拉加载更多
          </div>

          <!-- 没有更多评论的提示 -->
          <div v-if="!hasMore && !loading" class="no-more-tip">
            没有更多评论了
          </div>
        </div>
      </el-scrollbar>
    </div>
  </div>
</template>

<script setup>
import {ref, defineProps, watch} from 'vue'
import {Plus, Star, StarFilled} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/stores/UserStore'
import {
  createAttractionComment,
  getAttractionComments,
  deleteAttractionComment,
  uploadCommentImage,
  deleteCommentImage, addLikeComment,
} from "@/api/Attraction.js";
import {downloadUserAvatarByUserId, getUserInfo} from "@/api/User.js";
import {downloadImage} from "@/api/Image.js";
import thumbIcon from "@/assets/thumb.png";
import thumbLikedIcon from "@/assets/thumb_liked.png";

const props = defineProps({
  attractionId: Number
})

const attractionId = ref(null)
const emit = defineEmits(['comment-added'])

const comments = ref([])
const newComment = ref('')
const uploadedImages = ref([])
const currentUserId = useUserStore().userInfo.userId
const page = ref(1)
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const upload = ref(null)
const loading = ref(false)
const hasMore = ref(true)
const userLikes = ref([])

const totalComments = ref(0)      // 总评论数
const loadedComments = ref(0)     // 已加载的评论数
const pageSize = 5                // 每页加载的评论数




// 将 Base64 字符串转换为 Blob，然后创建一个 URL 对象
function base64ToBlob(base64String) {
  const byteCharacters = atob(base64String);
  const byteNumbers = new Array(byteCharacters.length);
  for (let i = 0; i < byteCharacters.length; i++) {
    byteNumbers[i] = byteCharacters.charCodeAt(i);
  }
  const byteArray = new Uint8Array(byteNumbers);
  return new Blob([byteArray], { type: 'image/png' });
}

//获取景点评论
const fetchComments = async () => {
  if (loading.value || !hasMore.value) return;
  loading.value = true;

  try {
    const res = await getAttractionComments(attractionId.value, page.value, pageSize);
    if (res.status === 'success') {
      // 更新总评论数
      totalComments.value = res.totalRecords || 0;
      page.value++;

      // 将返回的评论数据立即添加到评论列表中
      const newComments = res.data.map((comment) => ({
        ...comment,
        user: {
          username: '',
          avatarUrl: '',
        },
        imageUrls: comment.imageUrls || [], // 初始为评论中的 imageUrls，后续再更新
        isLikedByCurrentUser: false,
        likeCount: comment.likeCount || 0,
      }));

      comments.value = [...comments.value, ...newComments];
      // 更新已加载评论数
      loadedComments.value = comments.value.length;

      // 判断是否还有更多评论
      if (loadedComments.value >= totalComments.value) {
        hasMore.value = false;
      }

      // 为每条评论异步获取用户信息和图片
      for (const comment of newComments) {
        try {
          // 获取用户信息和头像
          const [userRes, avatarRes] = await Promise.all([
            getUserInfo(comment.userId),
            downloadUserAvatarByUserId(comment.userId),
          ]);

          const user = userRes.data;
          const avatarBlob = base64ToBlob(avatarRes.data);
          const userAvatarUrl = URL.createObjectURL(avatarBlob);

          // 下载评论图片
          const imagePromises = comment.imageUrls.map(async (url) => {
            const imageRes = await downloadImage(url);
            if (imageRes) {
              const imageBlob = base64ToBlob(imageRes.data);
              return URL.createObjectURL(imageBlob);
            }
            return null;
          });
          const imageUrls = (await Promise.all(imagePromises)).filter((url) => url !== null);

          // 更新评论列表中的对应评论
          const commentIndex = comments.value.findIndex((c) => c.commentId === comment.commentId);
          if (commentIndex !== -1) {
            comments.value[commentIndex].user.username = user.username;
            comments.value[commentIndex].user.avatarUrl = userAvatarUrl;
            comments.value[commentIndex].imageUrls = imageUrls;
          }
        } catch (err) {
          console.log('获取用户信息或图片失败:', err);
        }
      }
    } else {
      ElMessage.error('获取评论失败');
    }
  } catch (error) {
    ElMessage.error('获取评论失败');
    console.log(error);
  } finally {
    loading.value = false;
  }
};

//监听变化
watch(() => props.attractionId, (newAttractionId) =>{
  attractionId.value = newAttractionId
  comments.value = []
  page.value = 1
  loading.value = false
  hasMore.value = true
  fetchComments()
  totalComments.value = 0
  loadedComments.value = 0
}, { immediate: true })

//提交评论
const submitComment = async () => {
  if (!newComment.value.trim()) {
    ElMessage.warning('请输入评论内容')
    return
  }
  try {
    let keys = []
    if(uploadedImages.value.length > 0){
      //所有图片的key
       keys = await uploadedCommentImages()
    }
    const comment = {
      userId:currentUserId,
      attractionId: attractionId.value,
      content: newComment.value,
      imageUrls:keys
    }

    const res = await createAttractionComment(comment)

    if(res.status === 'success'){
      // 提取 uploadedImages 中的 url 值
      const imageUrls = uploadedImages.value.map(file => file.url)
      // 直接在前端添加新评论
      comments.value.unshift({
        ...comment,
        createdAt:Date.now(),
        user: {
          username: useUserStore().userInfo.username,
          avatarUrl: useUserStore().userInfo.avatarUrl
        },
        imageUrls:  imageUrls
      })
      newComment.value = ''
      emit('comment-added')
      upload.value.clearFiles()
      uploadedImages.value = []
      ElMessage.success('评论发表成功')
    }else{
      ElMessage.error('评论发表失败')
    }
  } catch (error) {
    ElMessage.error('评论评论失败')
    console.log(error)
  }
}

const deleteComment = async (commentId,imageUrls) => {
  try {
    const res = await deleteAttractionComment(commentId)
    if(res.status === 'success'){
      //删除评论照片
      for(let key of imageUrls){
        await deleteCommentImage(key)
      }
      page.value = 1
      // 直接在前端删除评论
      comments.value = comments.value.filter(comment => comment.commentId !== commentId)
      ElMessage.success('评论删除成功')
    }else{
      ElMessage.error('评论删除失败')
    }
  } catch (error) {
    ElMessage.error('评论删除失败')
  }
}
//评论图片处理
//只能单张单张选择
const handleChange = (file) => {
  const isImage = file.raw.type.startsWith('image/');
  const isLt2M = file.size / 1024 / 1024 < 2;

  if (!isImage) {
    ElMessage.error('只能上传图片文件!');
    upload.value.clearFiles()
    return false
  }
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过 2MB!');
    upload.value.clearFiles()
    return false
  }
  return true
}
//图片预览
const handlePictureCardPreview = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url
  dialogVisible.value = true
}

//上传图片到redis
const uploadedCommentImages = async () =>{
  try {
   let keys = []
    //将所有照片文件上传
    for (let file of uploadedImages.value) {
      //以文件的url做key
      const formData = new FormData()
      formData.append('file', file.raw)

      const res = await uploadCommentImage(currentUserId, formData)
      if (res.status === 'success') {
        keys.push(res.data)
      }else{
        ElMessage.error("评论图片上传失败")
        return keys
      }
    }
    ElMessage.success("评论图片上传成功")
    return keys
  }catch (error){
    console.log(error)
  }
}

//处理图片数量过多
const handleExceed = () =>{
  ElMessage.warning("最多只能上传三张照片")
}

//点赞或取消点赞 评论
const likeComment = async (comment) =>{
  try {
    const res = await addLikeComment(currentUserId, comment.commentId)
    if (res.status === 'success') {
      if(comment.isLikedByCurrentUser){
        comment.likeCount -= 1
        comment.isLikedByCurrentUser = false
      }else{
        comment.likeCount += 1
        comment.isLikedByCurrentUser = true
      }
    }else{
      ElMessage.error("点赞失败")
    }
  }catch (error){
    console.log(error)
    ElMessage.error("点赞异常")
  }
}

const handleUploadSuccess = (response) => {
  uploadedImages.value.push(response.url)
}

const formatDate = (date) => {
  return new Date(date).toLocaleString()
}


const loadMore = async () => {
  await fetchComments()
}
defineExpose({
  fetchComments
})

</script>

<style scoped>
.comment-section {
  margin-top: 40px;
}

.comment-input {
  margin-bottom: 20px;
}

.comment-actions {
  margin-top: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.comment-item {
  margin-bottom: 20px;
}

.comment-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 10px;
}

.comment-time {
  color: #999;
  font-size: 14px;
}

.comment-images {
  display: flex;
  gap: 10px;
  margin-top: 10px;
}

.comment-images .el-image {
  width: 100px;
  height: 100px;
  border-radius: 4px;
}

.comment-footer {
  margin-top: 10px;
  display: flex;
  justify-content: flex-end;
}

.loading-tip, .no-more-tip {
  text-align: center;
  padding: 10px;
  color: #999;
  font-size: 14px;
}
</style>
